<!DOCTYPE HTML>
<html>
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  
  <title>Dubbo之SPI基础使用 › 但行好事，莫问前程</title>
  <meta name="author" content="fengbo">
  
  <meta name="description" content="不想当架构师的程序员不是好厨师 ，不认为PHP是世界上最好的编程语言的Python开发者不是一个好的Javaer。">
  
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  <meta property="og:title" content="Dubbo之SPI基础使用">
  <meta property="og:site_name" content="但行好事，莫问前程">

  
    <meta property="og:image" content="undefined">
  

  <link href="/favicon.png" rel="icon">
  <link rel="alternate" href="/atom.xml" title="但行好事，莫问前程" type="application/atom+xml">
  <link rel="stylesheet" href="/css/style.css" media="screen" type="text/css">
  <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  

</head>
</html>

<body>
  <header id="header"><div class="meta inner">
  <h1><a href="/">但行好事，莫问前程</a></h1>
  <h2><a href="/">CV工程师，了解面向Google编程的基本原理，有三年使用Google经验，在通往程序员的道路上艰难的爬行着。</a></h2>
  <nav id="main-nav">
    <ul>
      
      <li><a href="/">Home</a></li>
      
      <li><a href="/archives">Archives</a></li>
      
      <li><a href="/atom.xml">RSS</a></li>
      
    </ul>
    <div class="clearfix"></div>
  </nav>
</div>
<div class="clearfix"></div>
</header>
  <div id="content" class="inner">
    <div id="main-col" class="alignleft"><div id="wrapper"><article class="post">
  <div class="post-content">
    <header>
      
  
    <h1 class="title">Dubbo之SPI基础使用</h1>
  

      
        <time datetime="2019-01-13T04:29:51.000Z">2019-01-13</time>
      
    </header>
    <div class="entry">
      
        <h3 id="SPI简介"><a href="#SPI简介" class="headerlink" title="SPI简介"></a>SPI简介</h3><p>SPI全称为Service Provider Interface，是一种服务发现机制。SPI的本质是将接口实现类的全限定名配置在文件中，并由服务加载器读取配置文件，加载实现类。这样可以在运行时，动态为接口替换实现类。正因此特性，我们可以很容易的通过SPI机制为我们的程序提供拓展功能。<br><a id="more"></a></p>
<h2 id="Java-SPI简单测试"><a href="#Java-SPI简单测试" class="headerlink" title="Java SPI简单测试"></a>Java SPI简单测试</h2><p>定义一个接口名称为Autobot。@SPI和@Adaptive是Dubbo注解，为了在Dubbo示例中可以复用该接口。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SPI</span>(<span class="string">"optimusPrime"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Autobot</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Adaptive</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">sayHello1</span><span class="params">(URL url)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Adaptive</span>(<span class="string">"test"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">sayHello2</span><span class="params">(Invoker invoker)</span></span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>定义两个实现类，分别为OptimusPrime和Bumblebee。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Bumblebee</span> <span class="keyword">implements</span> <span class="title">Autobot</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello1</span><span class="params">(URL url)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"Hello1, I am Bumblebee."</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello2</span><span class="params">(Invoker invoker)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"Hello, I am Bumblebee."</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OptimusPrime</span> <span class="keyword">implements</span> <span class="title">Autobot</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello1</span><span class="params">(URL url)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"Hello1, I am Optimus Prime."</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello2</span><span class="params">(Invoker invoker)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"Hello, I am Optimus Prime."</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>接下来在resource下创建META-INF/services文件夹，并在其中创建一个文件，名称为Autobot的全限定名spi.Autobot，内容为两个实现的全限定名。</p>
<pre><code>spi.OptimusPrime
spi.Bumblebee
</code></pre><p>测试代码如下：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SPITest</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testJava</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        ServiceLoader&lt;Autobot&gt; serviceLoader = ServiceLoader.load(Autobot<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">        System.out.println(<span class="string">"Java SPI"</span>);</span><br><span class="line">        <span class="keyword">for</span> (Autobot autobot : serviceLoader) &#123;</span><br><span class="line">            autobot.sayHello1(<span class="keyword">null</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h2 id="Dubbo-SPI简单测试"><a href="#Dubbo-SPI简单测试" class="headerlink" title="Dubbo SPI简单测试"></a>Dubbo SPI简单测试</h2><p>接口和实现类代码和上面Java SPI的代码相同。但是需要在resource下创建META-INF/dubbo文件夹，并在其中创建一个文件，名称为Autobot的全限定名spi.Autobot，内容如下。</p>
<pre><code>optimusPrime=spi.OptimusPrime
bumblebee=spi.Bumblebee
</code></pre><p>测试代码如下：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SPITest</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testDubbo</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        ExtensionLoader&lt;Autobot&gt; extensionLoader = ExtensionLoader.getExtensionLoader(Autobot<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">        System.out.println(<span class="string">"Dubbo SPI"</span>);</span><br><span class="line">        Autobot optimusPrime = extensionLoader.getExtension(<span class="string">"optimusPrime"</span>);</span><br><span class="line">        optimusPrime.sayHello1(<span class="keyword">null</span>);</span><br><span class="line">        Autobot bumblebee = extensionLoader.getExtension(<span class="string">"bumblebee"</span>);</span><br><span class="line">        bumblebee.sayHello1(<span class="keyword">null</span>);</span><br><span class="line">        <span class="comment">// 1.输出的是 ==&gt; Hello1, I am Optimus Prime.</span></span><br><span class="line">        Autobot autobot1 = extensionLoader.getAdaptiveExtension();</span><br><span class="line">        autobot1.sayHello1(URL.valueOf(<span class="string">"test"</span>));</span><br><span class="line">        <span class="comment">// 2.输出的是 ==&gt; Hello1, I am Bumblebee.</span></span><br><span class="line">        Autobot autobot2 = extensionLoader.getAdaptiveExtension();</span><br><span class="line">        autobot2.sayHello1(URL.valueOf(<span class="string">"test"</span>).addParameter(<span class="string">"autobot"</span>, <span class="string">"bumblebee"</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h3 id="Dubbo-SPI扩展点自适应装配"><a href="#Dubbo-SPI扩展点自适应装配" class="headerlink" title="Dubbo SPI扩展点自适应装配"></a>Dubbo SPI扩展点自适应装配</h3><p>自适应装配指的是Dubbo SPI会根据方法中传递的URL对象中的配置信息自动解析出需要调用的具体实现类。其中@Adaptive注解的值会和URL的addParameter(String key, String value)中的Key进行匹配，默认是接口名的首字母小写。而@SPI注解的值则代表URL对象的配置信息中没有可以和@Adaptive注解的值配置的值的时候的默认值。具体调用方式如上面的测试代码的1、2所示。<br>与此同时，ExtensionLoader还可以通过扫描扩展点实现类的所有setter方法来动态注入对应的实现类。实现步骤如下：</p>
<p>新建一个接口Robot。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SPI</span>(<span class="string">"robotImpl"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Robot</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Adaptive</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">sayHello1</span><span class="params">(URL url)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Adaptive</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">sayHello2</span><span class="params">(Invoker invoker)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>定义一个实现类RobotImpl。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RobotImpl</span> <span class="keyword">implements</span> <span class="title">Robot</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Autobot autobot;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAutobot</span><span class="params">(Autobot autobot)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.autobot = autobot;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello1</span><span class="params">(URL url)</span> </span>&#123;</span><br><span class="line">        autobot.sayHello1(url);</span><br><span class="line">        System.out.println(<span class="string">"hello1"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello2</span><span class="params">(Invoker invoker)</span> </span>&#123;</span><br><span class="line">        autobot.sayHello2(invoker);</span><br><span class="line">        System.out.println(<span class="string">"hello2"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>在META-INF/dubbo文件夹创建spi.Robot文件。名称为Robot的全限定名spi.Robot，内容为实现类的全限定名。</p>
<pre><code>robotImpl=spi.RobotImpl
robotFilter=spi.RobotFilterWrapper
</code></pre><p>上述代码会自动将Autobot对应的实现类注入到RobotImpl中。具体测试代码如下：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SPITest</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testDubbo2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Robot robot = ExtensionLoader.getExtensionLoader(Robot<span class="class">.<span class="keyword">class</span>).<span class="title">getAdaptiveExtension</span>()</span>;</span><br><span class="line">        System.out.println(<span class="string">"Dubbo2 SPI"</span>);</span><br><span class="line">        robot.sayHello2(<span class="keyword">new</span> MyInvoker());</span><br><span class="line">        System.out.println(<span class="string">"============================================="</span>);</span><br><span class="line">        robot.sayHello1(URL.valueOf(<span class="string">"test"</span>).addParameter(<span class="string">"autobot"</span>, <span class="string">"bumblebee"</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>输出如下：</p>
<pre><code>Dubbo2 SPI
Hello2, I am Bumblebee.
hello2
=============================================
Hello1, I am Bumblebee.
hello1
</code></pre><p>其中匹配方式除了直接传递URL对象，还可以传递Invoker接口的实现类，会根据该实现类的getUrl()方法返回的URL的实例进行匹配。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyInvoker</span> <span class="keyword">implements</span> <span class="title">Invoker</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Class <span class="title">getInterface</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Result <span class="title">invoke</span><span class="params">(Invocation invocation)</span> <span class="keyword">throws</span> RpcException </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> URL <span class="title">getUrl</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> URL.valueOf(<span class="string">"test"</span>).addParameter(<span class="string">"test"</span>, <span class="string">"bumblebee"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isAvailable</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">destroy</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h3 id="扩展点自动激活"><a href="#扩展点自动激活" class="headerlink" title="扩展点自动激活"></a>扩展点自动激活</h3><p>有些扩展类可以同时加载多个实现，此时，可以用自动激活来简化配置，如：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SPI</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Filter</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">testFilter</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Activate</span>(<span class="string">"test"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyFilter</span> <span class="keyword">implements</span> <span class="title">Filter</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testFilter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"filter"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>在META-INF/dubbo文件夹新建spi.Filter文件，内容为：</p>
<pre><code>myFilter=spi.MyFilter
</code></pre><h3 id="扩展点自动包装"><a href="#扩展点自动包装" class="headerlink" title="扩展点自动包装"></a>扩展点自动包装</h3><p>ExtensionLoader在加载扩展点时，如果加载到的扩展点有拷贝构造函数，则判定为扩展点代理类。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RobotFilterWrapper</span> <span class="keyword">implements</span> <span class="title">Robot</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Robot robot;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">RobotFilterWrapper</span><span class="params">(Robot robot)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.robot = robot;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello1</span><span class="params">(URL url)</span> </span>&#123;</span><br><span class="line">        robot.sayHello1(url);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sayHello2</span><span class="params">(Invoker invoker)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 根据invoker.getUrl()返回值加载Filter，因为URL中包含有Key为test的配置，所以会调用MyFilter</span></span><br><span class="line">        ExtensionLoader.getExtensionLoader(Filter<span class="class">.<span class="keyword">class</span>).<span class="title">getActivateExtension</span>(</span></span><br><span class="line">                invoker.getUrl(), "myFilter").forEach(Filter::testFilter);</span><br><span class="line">        robot.sayHello2(invoker);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>现在调用上面的测试类输出的值为：</p>
<pre><code>filter
Hello2, I am Bumblebee.
hello2
=============================================
Hello1, I am Bumblebee.
hello1
</code></pre>
      
    </div>
      
      <footer>
        
        
  
  <div class="tags">
    <a href="/tags/分布式/">分布式</a>
  </div>

        
  <div class="addthis addthis_toolbox addthis_default_style">
    
      <a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
    
    
      <a class="addthis_button_tweet"></a>
    
    
      <a class="addthis_button_google_plusone" g:plusone:size="medium"></a>
    
    
      <a class="addthis_button_pinterest_pinit" pi:pinit:layout="horizontal"></a>
    
    <a class="addthis_counter addthis_pill_style"></a>
  </div>
  <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js"></script>

      
      <div class="clearfix"></div>
      </footer>
  </div>
</article>

<!-- 来必力City版安装代码 -->
<!-- <div id="lv-container" data-id="city" data-uid="MTAyMC8yOTQ5MS82MDU5">
<script type="text/javascript">
   (function(d, s) {
       var j, e = d.getElementsByTagName(s)[0];

       if (typeof LivereTower === 'function') { return; }

       j = d.createElement(s);
       j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
       j.async = true;

       e.parentNode.insertBefore(j, e);
   })(document, 'script');
</script>
<noscript>为正常使用来必力评论功能请激活JavaScript</noscript>
</div> -->
<!-- City版安装代码已完成 -->

</div></div>
    <aside id="sidebar" class="alignright">
  
<div class="widget tagcloud">
  <h3 class="title">文章分类</h3>
  <div class="entry">
    <a href="/tags/JavaWeb/" style="font-size: 17.14px;">JavaWeb</a> <a href="/tags/Java基础/" style="font-size: 15.71px;">Java基础</a> <a href="/tags/Java高级特性/" style="font-size: 15.71px;">Java高级特性</a> <a href="/tags/Python/" style="font-size: 10px;">Python</a> <a href="/tags/Spring基础/" style="font-size: 14.29px;">Spring基础</a> <a href="/tags/WebRTC/" style="font-size: 10px;">WebRTC</a> <a href="/tags/其它/" style="font-size: 20px;">其它</a> <a href="/tags/分布式/" style="font-size: 11.43px;">分布式</a> <a href="/tags/硬件/" style="font-size: 12.86px;">硬件</a> <a href="/tags/计算机基础/" style="font-size: 18.57px;">计算机基础</a> <a href="/tags/设计模式/" style="font-size: 17.14px;">设计模式</a>
  </div>
</div>



    <div class="widget tagcloud">
    <h3 class="title">电子书</h3>
    <ul class="entry">
      <li class='link'><a href='http://www.duokan.com/' target="_blank">多看阅读</a>&nbsp;&nbsp;<a href='https://read.douban.com/' target="_blank">豆瓣阅读</a>&nbsp;&nbsp;<a href='http://e.dangdang.com/' target="_blank">当当阅读</a></li>
      <li class='link'><a href='http://www.ituring.com.cn/' target="_blank">图灵社区</a>&nbsp;&nbsp;<a href='https://www.epubit.com/' target="_blank">异步社区</a>&nbsp;&nbsp;<a href='https://www.geekbang.org/' target="_blank">极客空间</a></li>
    </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">友情链接</h3>
      <ul class="entry">
        
          <li class='link'><a href='http://www.cnblogs.com/jietang/' target="_blank">唐洁的博客</a></li>
        
          <li class='link'><a href='http://rednaxelafx.iteye.com/' target="_blank">R大的博客</a></li>
        
          <li class='link'><a href='http://www.hollischuang.com/' target="_blank">阿里大神的博客</a></li>
        
          <li class='link'><a href='http://blog.csdn.net/IT_faquir/' target="_blank">IT_faquir的专栏</a></li>
        
      </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">思维导图</h3>
      <ul class="entry">
        
          <li class='link'><a href='https://fengbo4213.github.io/img/开源协议.png' target="_blank">开源协议简介</a></li>
        
          <li class='link'><a href='https://www.processon.com/diagraming/5b0cf757e4b009aef58d4b9d' target="_blank">我的知识体系</a></li>
        
          <li class='link'><a href='https://www.processon.com/view/link/5a2a00e5e4b015e677290b4f' target="_blank">简单的网站架构</a></li>
        
      </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">在线手册</h3>
      <ul class="entry">
        
          <li class='link'><a href='http://v3.bootcss.com/' target="_blank">BootStrap官方手册</a></li>
        
          <li class='link'><a href='http://www.iconfont.cn/http://element.eleme.io/#/zh-CN/' target="_blank">阿里巴巴矢量图标库</a></li>
        
      </ul>
  </div>


  
<div class="widget tag">
  <h3 class="title">最新文章</h3>
  <ul class="entry">
    
      <li>
        <a href="/2123/08/30/基础之MySQL原理/">MySQL原理</a>
      </li>
    
      <li>
        <a href="/2024/01/01/其它之ClickHouse索引/">ClickHouse索引</a>
      </li>
    
      <li>
        <a href="/2023/12/17/其它之MySQL线程池/">MySQL线程池</a>
      </li>
    
      <li>
        <a href="/2023/12/16/其它之InnoDB性能优化基础/">InnoDB性能优化基础</a>
      </li>
    
      <li>
        <a href="/2023/12/03/其它之Java8之后的版本新特性/">Java8之后的版本新特性</a>
      </li>
    
  </ul>
</div>

</aside>
    <div class="clearfix"></div>
  </div>
  <footer id="footer" class="inner"><div class="alignleft">
  
  &copy; 2024 fengbo
  
</div>
<div class="clearfix"></div></footer>
  <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>



</body>
</html>

